﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO.Compression;
using System.IO;

namespace LogicBaseLibrary.Zip
{
    public class Compression
    {
        public static byte[] Compress(byte[] buffer)
        {
            MemoryStream msOutput = null;
            GZipStream gStream = null;
            byte[] retVal = null;
            try
            {
                msOutput = new MemoryStream();

                gStream = new GZipStream(msOutput, CompressionMode.Compress, false);
                gStream.Write(buffer, 0, buffer.Length);
                gStream.Flush();
                gStream.Close();
                retVal = msOutput.ToArray();

                return retVal;
            }
            catch { return retVal; }
            finally
            {
                gStream.Dispose();
                msOutput.Dispose();
            }
        }
        public static byte[] DeCompress(byte[] buffer)
        {
            MemoryStream msInput = null;
            MemoryStream msOutput = null;
            GZipStream gStream = null;
            byte[] retVal = null;
            try {
                msInput = new MemoryStream(buffer);
                msOutput = new MemoryStream();

                gStream = new GZipStream(msInput, CompressionMode.Decompress, false);
                byte[] byteTmp = new byte[102400];
                int readcount = gStream.Read(byteTmp,0,byteTmp.Length);
                while(readcount>0)
                {
                    msOutput.Write(byteTmp, 0, readcount);
                    readcount = gStream.Read(byteTmp, 0, byteTmp.Length);
                }

                gStream.Close();
                msOutput.Flush();
                msOutput.Close();

                retVal = msOutput.ToArray();
                return retVal;
            }
            catch { return retVal; }
            finally {
                msInput.Dispose();
                msOutput.Dispose();
                gStream.Dispose();
            }
        }

        public static Stream Compress(Stream fsSource)
        {
            MemoryStream ms = new MemoryStream();
            fsSource.Seek(0, SeekOrigin.Begin);

            GZipStream gStream = new GZipStream(ms, CompressionMode.Compress, true);
            
            byte[] buffer = new byte[1024000];
            int readCount =fsSource.Read(buffer,0,buffer.Length); 
            while(readCount>0)
            {
                gStream.Write(buffer, 0, readCount);
                readCount = fsSource.Read(buffer, 0, buffer.Length);
            }
            gStream.Flush();
            gStream.Close();
            return ms;
        }

        public static Stream DeCompress(Stream fsSource)
        {
            //MemoryStream ms = new MemoryStream();
            string tmpfile = Path.GetTempFileName();

            FileStream fs = new FileStream(tmpfile,FileMode.Create,FileAccess.ReadWrite);
            GZipStream gStream = new GZipStream(fsSource, CompressionMode.Decompress, true);
            
            byte[] buffer = new byte[1024000];
            int readCount = gStream.Read(buffer, 0, buffer.Length);
            while (readCount > 0)
            {
                fs.Write(buffer, 0, readCount);
                readCount = gStream.Read(buffer, 0, buffer.Length);
            }
            gStream.Close();
            fsSource.Close();
            return fs;
        }
        public static void DeCompress(Stream fsSource, string outFilename)
        {   
            FileStream fs  = null;
            GZipStream gStream = null;
            try
            {
                fs = new FileStream(outFilename, FileMode.Create, FileAccess.ReadWrite);
                gStream = new GZipStream(fsSource, CompressionMode.Decompress, true);

                byte[] buffer = new byte[1024000];
                int readCount = gStream.Read(buffer, 0, buffer.Length);
                while (readCount > 0)
                {
                    fs.Write(buffer, 0, readCount);
                    readCount = gStream.Read(buffer, 0, buffer.Length);
                }
            }
            catch { }
            finally {
                gStream.Close();
                fsSource.Close();
                fs.Flush();
                fs.Close();
            }
        }

    }
}
